/**
 * Created by lional on 16/10/2.
 */

jGame.ListView = ccui.ListView.extend(/** @lends jGame.ListView# */{

    _data:null,
    _controller:null,
    _defaultItem:null,
    _defaultItemJson:null,
    _defaultEmptyText:null,
    _isClear: false,
    _isInitList: false,
    _initListCells: null,
    _listCells: null,
    _listStartIndex: 0,
    _listEndIndex: 0,
    _listCallback: null,
    _listDelayTime: 0.0,
    _cellSize: null,
    
    ctor: function () {
        this._super();
        //cc.log("jGame.ListView#ctor()");
        this._isClear = false;
        this._isInitList = false;
        this._initListCells = [];
        this._listCells = [];
        this._listStartIndex = 0;
        this._listEndIndex = 0;
        this._listDelayTime = 0.0;
        this._cellSize = cc.size(0, 0);
    },

    onExit: function () {
        if(this._isInitList) {
            this.unschedule(this.UpdateListView);
        }
        for(var i = 0; i < this._listCells.length; i++) {
            for(var n = 0; n < this._listCells[i].length; n++) {
                this._listCells[i][n] = null;
            }
            this._listCells[i] = null;
        }
        this._listCells = null;
        for(var i = 0; i < this._initListCells.length; i++) {
            for(var n = 0; n < this._initListCells[i].length; n++) {
                var child = this._initListCells[i][n];
                child.stopAllActions();
                this.setItemRetain(child, false);
                child = null;
                this._initListCells[i][n] = null;
            }
            this._initListCells[i] = null;
        }
        this._initListCells = null;
        this._cellSize = null;
        this.removeAllListItems();
        this._super();
        //cc.log("jGame.ListView[" + this.name + "]#onExit()");
    },

    setController: function(controller){
        this._controller = controller;
    },

    getController: function(){
        return this._controller;
    },

    setItemFromJsonFile: function (json_file_path) {
        if(!json_file_path) return;

        var itemNode = jGame.load(json_file_path, "res/");
        if(itemNode && itemNode.node) {
            var default_item = new jGame.Layout();
            default_item.setContentSize(itemNode.node.getContentSize());

            var widgetChildren = itemNode.node.getChildrenCount();
            while (widgetChildren.length > 0) {
                var child = widgetChildren[0];
                child.removeFromParent();
                default_item.addChild(child);
                if(widgetChildren[0] === child) {
                    widgetChildren.splice(0, 1);
                }
            }
            this._defaultItem = default_item;
        }
    },

    setItemJsonFile: function (json_file_path) {
        this._defaultItemJson = json_file_path;
    },

    setEmptyText: function (text) {
        this._defaultEmptyText = text;
        this._showEmptyText();
    },

    _showEmptyText: function () {
        if(this.getItems().length == 0) {
            var defaultEmptyText = this.getChildByName("defaultEmptyText");
            if(!defaultEmptyText) {
                if(typeof this._defaultEmptyText === "string") {
                    var Panel = new jGame.Layout();
                    Panel.setContentSize(this.width, this.height);
                    var Text = new jGame.Text(this._defaultEmptyText, "Helvetica", 48);
                    Panel.addChild(Text);
                    Panel.setName("defaultEmptyText");
                    Text.setAnchorPoint(0.5, 0.5);
                    Text.setPosition(this.width/2, this.height/2);
                    this.addChild(Panel);
                }
            }
            this._isClear = false;
        }else {
            var defaultEmptyText = this.getChildByName("defaultEmptyText");
            if(defaultEmptyText) {
                defaultEmptyText.removeFromParent();
            }
        }
    },

    removeAllChildren: function() {
        //cc.log("removeAllChildren");
    },

    removeAllListItems: function() {
        this.stopAllActions();
        this.stopAutoScroll();
        ccui.ListView.prototype.removeAllChildren.call(this);
    },

    UpdateListView: function(dt) {
        if(this._isInitList) {
            this._listDelayTime = 0.0;
            var instance = this;
            if(this.getDirection() == ccui.ScrollView.DIR_VERTICAL) {
                var childs = this.getItems();
                var defaultEmptyText = this.getChildByName("defaultEmptyText");
                if(childs.length > 0 && !defaultEmptyText) {
                    var pos = this.getInnerContainerPosition();
                    var innerContainerSize = this.getInnerContainerSize();
                    var startRow = 0;
                    var endRow = 0;
                    if (innerContainerSize.height > this.height) {
                        var posY = innerContainerSize.height - this.height;
                        posY += pos.y;
                        startRow = Math.floor(posY / childs[0].height);
                        if(startRow < 0) {
                            startRow = 0;
                        }
                        var listContentSize = this.getContentSize();
                        endRow = startRow + (Math.ceil(listContentSize.height / childs[0].height));
                    } else {
                        startRow = 0;
                        endRow = childs.length;
                    }
                    if(endRow > childs.length) {
                        endRow = childs.length;
                        startRow = endRow - (Math.ceil(listContentSize.height / childs[0].height));
                    }
                    if(startRow < 0) {
                        startRow = 0;
                        endRow = startRow + (Math.ceil(listContentSize.height / childs[0].height));
                    }
                    if(startRow != this._listStartIndex || endRow != this._listEndIndex) {
                        if(this._listStartIndex >= 0 && this._listEndIndex > 0) {
                            for (var i = this._listStartIndex; i <= this._listEndIndex; i++) {
                                if (i < childs.length) {
                                    if (i >= startRow && i < endRow) {

                                    } else {
                                        if (childs[i].getChildrenCount() > 0) {
                                            var cells = [];
                                            var widgetChildren = childs[i].getChildren();
                                            while (widgetChildren.length > 0) {
                                                var child = widgetChildren[0];
                                                cells.push(child);
                                                child.removeFromParent();
                                                if(widgetChildren[0] === child) {
                                                    widgetChildren.splice(0, 1);
                                                }
                                            }
                                            this._listCells.push(cells);
                                        }
                                    }
                                }
                            }
                        }
                        this._listStartIndex = startRow;
                        this._listEndIndex = endRow;
                        for (var i = this._listStartIndex; i <= this._listEndIndex; i++) {
                            if (i < childs.length) {
                                var default_item = childs[i];
                                if (default_item.getChildrenCount() <= 0) {
                                    var cellChild = this.GetListCell();
                                    if (cellChild && cellChild.length > 0) {
                                        for(var n = 0; n < cellChild.length; n++) {
                                            var child = cellChild[n];
                                            default_item.addChild(child);
                                            if (child.getNumberOfRunningActions() == 0) {
                                                child.stopAllActions();
                                                child.x = child.width;
                                                child.runAction(cc.moveTo(0.3 + this._listDelayTime, cc.p(child._srcX, child._srcY)));
                                            }
                                            cellChild[n] = null;
                                        }
                                        cellChild = null;
                                        this._listDelayTime += 0.1;
                                        jGame.setAllChildrenController(default_item, instance._controller);
                                        if (typeof this._listCallback === "function") {
                                            this._listCallback(default_item.getTag(), default_item, default_item._indexData);
                                        }
                                    }
                                } else {
                                    if (typeof this._listCallback === "function") {
                                        this._listCallback(default_item.getTag(), default_item, default_item._indexData);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    },

    GetListCell: function() {
        if(this._listCells) {
            if (this._listCells.length > 0) {
                var listCell = this._listCells[0];
                this._listCells.splice(0, 1);
                return listCell;
            }
        }
        return null;
    },

    refresh: function () {
        this.setDefaultItemData(this._data, this._listCallback, this._defaultItemJson);
    },

    setDefaultItemData: function (data, callback, path) {
        this._listCallback = callback;
        this.stopAllActions();
        this.stopAutoScroll();
        this.removeAllChildren();
        this._data = data;
        if(typeof path === "string")this._defaultItemJson = path;
        if(!this._defaultItemJson || !data) return;
        if(!this._isClear) {
            this.removeAllListItems();
            this._isClear = true;
        }
        var instance = this;
        var cellContentSize = this._cellSize;
        var listContentSize = this.getContentSize();
        var initSize = 1;
        if(instance.getDirection() == ccui.ScrollView.DIR_VERTICAL) {
            if (!this._isInitList) {
                this._isInitList = true;
                this._initListCells = [];
                this._listCells = [];
                for (var i = 0; i < initSize; i++) {
                    var itemNode = jGame.load(this._defaultItemJson, "res/").node;
                    if (itemNode) {
                        var initCells = [];
                        var cells = [];
                        var widgetChildren = itemNode.getChildren();
                        while (widgetChildren.length > 0) {
                            var child = widgetChildren[0];
                            child._srcX = child.x;
                            child._srcY = child.y;
                            this.setItemRetain(child, true);
                            initCells.push(child);
                            cells.push(child);
                            child.removeFromParent();
                            if(widgetChildren[0] === child) {
                                widgetChildren.splice(0, 1);
                            }
                        }
                        this._initListCells.push(initCells);
                        this._listCells.push(cells);
                        if(i == 0) {
                            cellContentSize = itemNode.getContentSize();
                            initSize = Math.ceil(listContentSize.height / cellContentSize.height);
                            this._cellSize = cellContentSize;
                        }
                        itemNode = null;
                    }
                }
                this.schedule(this.UpdateListView);
            } else {
                initSize = Math.ceil(listContentSize.height / cellContentSize.height);
            }
        }
        this._listStartIndex = 0;
        this._listEndIndex = initSize;
        var count = 0;
        var addCount = 0;
        var childs = this.getItems();
        for(var index in data) {
            if(count < childs.length) {
                if (typeof callback === "function") {
                    var default_item = childs[count];
                    default_item.setVisible(true);
                    default_item.setTag(count);
                    default_item._indexData = index;
                    count++;
                }
            } else {
                var default_item = new jGame.Layout();
                default_item.setTag(count);
                default_item._indexData = index;
                default_item.setContentSize(cellContentSize);
                instance.pushBackCustomItem(default_item);
                count++;
                addCount++;
            }
        }
        childs = this.getItems();
        var size = childs.length;
        for(var i = count; i < size; i++) {
            if(childs[i].getChildrenCount() > 0) {
                var cells = [];
                var widgetChildren = childs[i].getChildren();
                while (widgetChildren.length > 0) {
                    var child = widgetChildren[0];
                    cells.push(child);
                    child.removeFromParent();
                    if(widgetChildren[0] === child) {
                        widgetChildren.splice(0, 1);
                    }
                }
                this._listCells.push(cells);
            }
        }
        for(var i = count; i < size; i++) {
            this.removeLastItem();
        }
        if(this.getDirection() == ccui.ScrollView.DIR_VERTICAL) {
            var pos = this.getInnerContainerPosition();
            if(addCount > 0) {
                pos.y -= (addCount * cellContentSize.height);
            } else {
                if(size - count > 0) {
                    pos.y += ((size - count) * cellContentSize.height);
                    if (pos.y > 0) {
                        pos.y = 0;
                    }
                }
            }
            this.doLayout();
            var contentSize = this.getContentSize();
            var innerContainerSize = this.getInnerContainerSize();
            var minY = contentSize.height - innerContainerSize.height;
            if (pos.y > minY) {
                this.setInnerContainerPosition(pos);
            }
            this._listStartIndex = -1;
            this._listEndIndex = -1;
        }
    },

    setDefaultItemDataOld: function (data, callback, path) {
        this.stopAllActions();
        this.stopAutoScroll();
        this.removeAllChildren();
        this.removeAllListItems();
        this._data = data;
        if(typeof path === "string")this._defaultItemJson = path;
        if(!this._defaultItemJson || !data) return;
        var count = 0;
        for(var index in data) {
            var itemNode = jGame.load(this._defaultItemJson, "res/");
            if(itemNode && itemNode.node) {
                var default_item =  new jGame.Layout();
                default_item.setTag(count);
                default_item.setContentSize(itemNode.node.getContentSize());

                var widgetChildren = itemNode.node.getChildren();
                while (widgetChildren.length > 0) {
                    var child = widgetChildren[0];
                    child.removeFromParent();
                    default_item.addChild(child);
                    if(widgetChildren[0] === child) {
                        widgetChildren.splice(0, 1);
                    }
                }
                jGame.setAllChildrenController(default_item, this._controller);
                if(default_item.width == 0 || default_item.height == 0) {
                    cc.log("Warning : list item width or height is 0.");
                }
                this.pushBackCustomItem(default_item);
                if(typeof callback === "function") {
                    callback(count, default_item, index);
                }
                count++;
            }
        }
        //this._showEmptyText();
    },

    // setDefaultItemData: function (data, callback, path) {
    //     this._data = data;
    //     if(typeof path === "string") {
    //         this.setItemFromJsonFile(path);
    //     }else if(path instanceof ccui.Widget){
    //         this._defaultItem = path;
    //     }
    //     if(!this._defaultItem || !data) return;
    //     var count = 0;
    //     for(var index in data) {
    //         var default_item =  jGame.clone(this._defaultItem);
    //         default_item.setTag(count);
    //         jGame.setAllChildrenController(default_item, this._controller);
    //         if (default_item.width == 0 || default_item.height == 0) {
    //             cc.log("Warning : list item [" + index + "] width or height is 0.");
    //         }
    //         this.pushBackCustomItem(default_item);
    //         if(typeof callback === "function") {
    //             callback(count, default_item, index);
    //         }
    //         count++;
    //     }
    // },

    setSelectCallbackName: function (callBackName) {
        var widget = this;
        var callBack = function(sender, type){
            if(typeof widget["_controller"] === "object" && typeof widget["_controller"][callBackName] === "function"){
                if(typeof widget["_controller"]["trace"] === "function")widget["_controller"]["trace"](sender, type);
                widget["_controller"][callBackName](sender, type);
            }
            else if(typeof widget[callBackName] === "function")
                widget[callBackName](sender, type);
        };
        this.addEventListener(callBack, this);
    },

});

jGame.CustomTableViewCell = cc.TableViewCell.extend({
    draw:function (ctx) {
        this._super(ctx);
    }
});

jGame.TableView = ccui.Layout.extend(/** @lends jGame.TableView# */{

    _tableView: null,
    _data:null,
    _dataKeys:null,
    _defaultItem:null,
    _defaultItemJson:null,
    _defaultEmptyText:null,
    _selectCallback:null,
    _tableCellCallback:null,

    ctor: function () {
        this._super();
        cc.log("jGame.TableView#ctor()");
    },

    _initTableView: function (widget, height) {
        var locWidth = widget;
        var locHeight = height;
        if (widget === undefined) {
            locWidth = 0;
            locHeight = 0;
        }else  if (height === undefined) {
            locWidth = widget.width;
            locHeight = widget.height;
        }

        var tbView = this.getChildByName("_tableView");
        if(tbView) {
            this.removeChild(tbView);
        }
        this._tableView = new cc.TableView(this, cc.size(locWidth, locHeight));
        this._tableView.setName("_tableView");
        this._tableView.setDelegate(this);
        this._tableView.setVerticalFillOrder(cc.TABLEVIEW_FILL_TOPDOWN);
        this.addChild(this._tableView);
        this._tableView.reloadData();
        this._tableView.setTouchEnabled(true);
        //this.setOneByOneCallbackName("onTableViewTouchBegan", "onTableViewTouchMoved", "onTableViewTouchEnded", "onTableViewTouchCancelled");
    },

    setItemFromJsonFile: function (json_file_path) {
        if(!json_file_path) return;

        var itemNode = jGame.load(json_file_path, "res/");
        if(itemNode && itemNode.node) {
            var default_item = new jGame.Layout();
            default_item.setContentSize(itemNode.node.getContentSize());

            var widgetChildren = itemNode.node.getChildren();
            while (widgetChildren.length > 0) {
                var child = widgetChildren[0];
                child.removeFromParent();
                default_item.addChild(child);
                if(widgetChildren[0] === child) {
                    widgetChildren.splice(0, 1);
                }
            }
            this._defaultItem = default_item;
        }
    },

    setItemJsonFile: function (json_file_path) {
        this._defaultItemJson = json_file_path;
    },

    setEmptyText: function (text) {
        this._defaultEmptyText = text;
        this._showEmptyText();
    },

    _showEmptyText: function () {
        if(!this._dataKeys || this._dataKeys.length == 0) {
            var defaultEmptyText = this.getChildByName("defaultEmptyText");
            if(!defaultEmptyText) {
                if(typeof this._defaultEmptyText === "string") {
                    var Panel = new jGame.Layout();
                    Panel.setContentSize(this.width, this.height);
                    var Text = new jGame.Text(this._defaultEmptyText, "Helvetica", 48);
                    Panel.addChild(Text);
                    Panel.setName("defaultEmptyText");
                    Text.setAnchorPoint(0.5, 0.5);
                    Text.setPosition(this.width/2, this.height/2);
                    this.addChild(Panel);
                }
            }
        }else {
            var defaultEmptyText = this.getChildByName("defaultEmptyText");
            if(defaultEmptyText) {
                defaultEmptyText.removeFromParent();
            }
        }
    },

    setDefaultItemData: function (data, callback, path) {

        this.removeAllChildren();

        this._data = data;
        this._dataKeys = [];
        var count = 0;
        for(var index in data) {
            this._dataKeys[count] = index;
            count++;
        }
        this._tableCellCallback = callback;
        if(typeof path === "string")this._defaultItemJson = path;
        
        this._tableView.reloadData();
        this._showEmptyText();
    },

    setSelectCallbackName: function (callBackName) {
        var widget = this;
        this._selectCallback = function(sender, type){
            if(typeof widget["_controller"] === "object" && typeof widget["_controller"][callBackName] === "function"){
                if(typeof widget["_controller"]["trace"] === "function")widget["_controller"]["trace"](sender, type);
                widget["_controller"][callBackName](sender, type);
            }
            else if(typeof widget[callBackName] === "function")
                widget[callBackName](sender, type);
        };
    },

    scrollViewDidScroll:function (view) {

    },

    scrollViewDidZoom:function (view) {

    },

    tableCellTouched:function (table, cell) {
        cc.log("cell touched at index: " + cell.getIdx());
        if(this._selectCallback) {

        }
    },

    tableCellTouched2:function () {
        cc.log("cell touched at index: ");
    },

    tableCellSizeForIndex:function (table, idx) {
        if (this._defaultItemJson) {
            var itemNode = jGame.load(this._defaultItemJson, "res/");
            if(itemNode && itemNode.node) {
                return itemNode.node.getContentSize();
            }
        }
        return cc.size();
    },

    tableCellAtIndex:function (table, idx) {
        var count = parseInt(idx);
        var cell = table.dequeueCell();
        if (!cell) {
            cell = new jGame.CustomTableViewCell();
            var itemNode = jGame.load(this._defaultItemJson, "res/");
            if(itemNode && itemNode.node) {
                var default_item = new jGame.Layout();
                default_item.setTag(count);
                default_item.setContentSize(itemNode.node.getContentSize());

                var widgetChildren = itemNode.node.getChildren();
                while (widgetChildren.length > 0) {
                    var child = widgetChildren[0];
                    child.removeFromParent();
                    default_item.addChild(child);
                    if(widgetChildren[0] === child) {
                        widgetChildren.splice(0, 1);
                    }
                }
                jGame.setAllChildrenController(default_item, this._controller);
                if (default_item.width == 0 || default_item.height == 0) {
                    cc.log("Warning : list item width or height is 0.");
                }
                cell.addChild(default_item);
                if(this._tableCellCallback) {
                    this._tableCellCallback(count, default_item, this._dataKeys[count]);
                }
            }
        } else {
            var default_item = cell.getChildren()[0];
            if(this._tableCellCallback) {
                this._tableCellCallback(count, default_item, this._dataKeys[count]);
            }
        }

        return cell;
    },

    numberOfCellsInTableView:function (table) {
        return this._dataKeys?this._dataKeys.length:0;
    },

    setDirection: function (directionType) {
        if(directionType == ccui.ScrollView.DIR_VERTICAL) {
            this._tableView.setDirection(cc.SCROLLVIEW_DIRECTION_VERTICAL);
        }else {
            this._tableView.setDirection(cc.SCROLLVIEW_DIRECTION_HORIZONTAL);
        }
    },

    setGravity: function (gravity) {
        //todo 设置gravity
    },

    setBounceEnabled: function (bounceEnabled) {
        //todo 设置反弹
    },

    setItemsMargin: function (itemMargin) {
        //todo 设置item间隔
    },

    setInnerContainerSize: function (widget, height) {
        this._initTableView(widget, height);
    },

    removeAllChildren: function (cleanup) {
        var widgetChildren = this.getChildren();
        while (widgetChildren.length > 0) {
            var child = widgetChildren[0];
            if(child.getName() != "_tableView") {
                this.removeChild(child, cleanup);
                if(widgetChildren[0] === child) {
                    widgetChildren.splice(0, 1);
                }
            }
        }
    },

});